package actor

import (
	"sync"
)

type messageEnvelope struct {
	msg    interface{}
	sender *PID
}

var gMessageEnvelopePool = sync.Pool{}

func produceMessageEnvelope() *messageEnvelope {
	if me, ok := gMessageEnvelopePool.Get().(*messageEnvelope); ok {
		return me
	}
	return &messageEnvelope{}
}

func recycleMessageEnvelope(me *messageEnvelope) {
	gMessageEnvelopePool.Put(me)
	me = nil
}

// SystemMessage 被保留用于由actor系统使用的生命周期的消息
type SystemMessage interface {
	SystemMessage()
}

// Restarted 当由于故障系统正在重新启动该actor时，将消息发送给actor
type Restarting struct {
	messageEnvelope
}

// Restarted 当由于故障系统正在重新启动该actor时，将消息发送给actor
type Restarted struct {
	messageEnvelope
}

// Stopping 在actor停止之前被发送给actor
type Stopping struct {
	messageEnvelope
}

// Stopped 此消息actor一被停止就发送。停止的actor将不会再收到消息
type Stopped struct {
	messageEnvelope
}

// Started 此消息当actor已经开始并准备好开始接收消息时发送。
type Started struct {
	messageEnvelope
}

// Restart 由actor系统发送的消息，用于控制actor的生命周期
type Restart struct {
	messageEnvelope
}

func (*Started) SystemMessage()    {}
func (*Stop) SystemMessage()       {}
func (*Watch) SystemMessage()      {}
func (*Unwatch) SystemMessage()    {}
func (*Terminated) SystemMessage() {}
func (*Restart) SystemMessage()    {}

var (
	restartingMessage interface{} = &Restarting{}
	restartedMessage  interface{} = &Restarted{}
	stoppingMessage   interface{} = &Stopping{}
	stoppedMessage    interface{} = &Stopped{}
	poisonPillMessage interface{} = &PoisonPill{}
)

var (
	startedMessage interface{} = &Started{}
	stopMessage    interface{} = &Stop{}
	restartMessage interface{} = &Restart{}
)
